package log

import (
	"strconv"
	"sync"

	sutil "gitee.com/simplexyz/simplego/util"
)

type IRecord interface {
	Bytes() []byte
	Level() Level
	Clone() IRecord
	reset()
}

type record struct {
	timestamp string
	level     Level
	content   string
	path      string
	line      int
	bytes     []byte
}

func (r *record) reset() {
	r.timestamp = ""
	r.level = 0
	r.content = ""
	r.path = ""
	r.line = 0
	r.bytes = nil
}

func (r *record) buildBytes() {
	buffer := sutil.GetBuffer()
	defer sutil.PutBuffer(buffer)

	// write timestamp
	//buffer.WriteString("[")
	buffer.WriteString(r.timestamp)
	//buffer.WriteString("]")
	buffer.WriteString(" ")

	// write level prefix
	buffer.WriteString(r.level.Prefix())
	buffer.WriteString(" ")

	if r.path != "" {
		// write caller
		buffer.WriteString(r.path)
		buffer.WriteString(":")
		buffer.WriteString(strconv.FormatInt(int64(r.line), 10))
		buffer.WriteString(" ")
	}

	// write content
	buffer.WriteString(r.content)

	// new line
	buffer.WriteString("\n")

	r.bytes = sutil.CopyBytes(buffer.Bytes())
}

func (r *record) Bytes() []byte {
	return r.bytes
}

func (r *record) Level() Level {
	return r.level
}

func (r *record) Clone() IRecord {
	n := createRecord()
	n.level = r.level
	if r.bytes == nil {
		n.timestamp = r.timestamp
		n.content = r.content
		n.path = r.path
		n.line = r.line
	} else {
		n.bytes = sutil.CopyBytes(r.bytes)
	}
	return n
}

var gRecordPool = sync.Pool{}

func createRecord() *record {
	r, ok := gRecordPool.Get().(*record)
	if !ok || r == nil {
		r = &record{}
	}
	return r
}

func destroyRecord(r IRecord) {
	if r == nil {
		return
	}
	r.reset()
	gRecordPool.Put(r)
}
